from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from bson.objectid import ObjectId
from datetime import datetime

from app.extensions import db, login_manager


class User(UserMixin):
    def __init__(self, username, email, password=None, role='user', **kwargs):
        self.username = username
        self.email = email
        self.password_hash = generate_password_hash(password) if password else None
        self.role = role
        self.created_at = kwargs.get('created_at', datetime.utcnow())
        self.last_login = kwargs.get('last_login', datetime.utcnow())
        self.favorites = kwargs.get('favorites', [])
        self.settings = kwargs.get('settings', {'theme': 'light', 'language': 'zh'})
        self._id = kwargs.get('_id', None)
    
    def get_id(self):
        return str(self._id)
    
    def check_password(self, password):
        if self.password_hash:
            return check_password_hash(self.password_hash, password)
        return False
    
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)
    
    def is_admin(self):
        return self.role == 'admin'
    
    def to_dict(self):
        return {
            'username': self.username,
            'email': self.email,
            'role': self.role,
            'created_at': self.created_at,
            'last_login': self.last_login,
            'favorites': self.favorites,
            'settings': self.settings
        }
    
    @classmethod
    def find_by_id(cls, user_id):
        user_data = db.db.users.find_one({'_id': ObjectId(user_id)})
        if not user_data:
            return None
        user_data['_id'] = user_data['_id']
        return cls(**user_data)
    
    @classmethod
    def find_by_username(cls, username):
        user_data = db.db.users.find_one({'username': username})
        if not user_data:
            return None
        return cls(**user_data)
    
    @classmethod
    def find_by_email(cls, email):
        user_data = db.db.users.find_one({'email': email})
        if not user_data:
            return None
        return cls(**user_data)
    
    def save(self):
        user_data = self.to_dict()
        if self._id:
            db.db.users.update_one({'_id': self._id}, {'$set': user_data})
        else:
            result = db.db.users.insert_one(user_data)
            self._id = result.inserted_id
        return self
    
    def add_favorite(self, tool_id):
        if not any(fav['tool_id'] == tool_id for fav in self.favorites):
            self.favorites.append({
                'tool_id': tool_id,
                'added_at': datetime.utcnow()
            })
            db.db.users.update_one(
                {'_id': self._id},
                {'$set': {'favorites': self.favorites}}
            )
    
    def remove_favorite(self, tool_id):
        self.favorites = [fav for fav in self.favorites if fav['tool_id'] != tool_id]
        db.db.users.update_one(
            {'_id': self._id},
            {'$set': {'favorites': self.favorites}}
        )


@login_manager.user_loader
def load_user(user_id):
    return User.find_by_id(user_id) 